package com.awesome.todo.database;

import com.awesome.todo.User;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorIndexOutOfBoundsException;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

/**
 * This is the class that handles all database interaction with the User table.
 * This is a comprehensive layer on top of the internal SQLite database. This is
 * the *ONLY* place that handles SQLite inserts, queries, and deletes to the
 * User table. Other classes must call methods from this class if they wish to
 * use data contained in the database.
 * 
 * @author doug
 * 
 */
public class UserDataSource {

	private SQLiteDatabase database;
	private UserTable userTable;
	@SuppressWarnings("static-access")
	private String[] allColumns = { userTable.COLUMN_ID, userTable.COLUMN_NAME,
			userTable.COLUMN_EMAIL, userTable.COLUMN_LOGIN,
			userTable.COLUMN_PASSWORD };

	public UserDataSource(Context context) {
		userTable = new UserTable(context);
	}

	/**
	 * This opens the User table for writing.
	 * 
	 * @throws SQLException
	 */
	public void open() throws SQLException {
		database = userTable.getWritableDatabase();
	}

	/**
	 * This closes the User table.
	 */
	public void close() {
		userTable.close();
	}

	/**
	 * This inserts a new row in the User table and returns a User object with
	 * the corresponding values.
	 * 
	 * @param name
	 *            the user name
	 * @param email
	 *            the user email
	 * @param login
	 *            the user login
	 * @param password
	 *            the user password
	 * @return the new user
	 */
	public User createUser(String name, String email, String login,
			String password) {

		this.open();
		ContentValues values = new ContentValues();
		values.put(UserTable.COLUMN_NAME, name);
		values.put(UserTable.COLUMN_EMAIL, email);
		values.put(UserTable.COLUMN_LOGIN, login);
		values.put(UserTable.COLUMN_PASSWORD, password);

		long insertId = database.insert(UserTable.TABLE_USER, null, values);

		Cursor cursor = database.query(UserTable.TABLE_USER, allColumns,
				UserTable.COLUMN_ID + " = " + insertId, null, null, null, null);

		Log.i(UserDataSource.class.toString(), "New user created with id: "
				+ insertId);
		cursor.moveToFirst();
		User newUser = cursorToUser(cursor);
		cursor.close();
		this.close();
		return newUser;
	}

	/**
	 * This deletes the row in the User table corresponding to the ID value of
	 * the passed in User object
	 * 
	 * @param user
	 *            the user to be deleted
	 */
	public void deleteUser(User user) {
		this.open();
		long id = user.getId();
		System.out.println("User deleted with id: " + id);
		database.delete(UserTable.TABLE_USER, UserTable.COLUMN_ID + " = " + id,
				null);
		this.close();
	}

	/**
	 * This returns the user matching the given login and password or null if
	 * there is no match
	 * 
	 * @param login
	 *            the user's login
	 * @param password
	 *            the user's password
	 * @return the new User or null if no match
	 */
	public User tryUserLogin(String login, String password) {

		this.open();
		Cursor cursor = database.query(UserTable.TABLE_USER, allColumns,
				UserTable.COLUMN_LOGIN + " = '" + login + "' AND "
						+ UserTable.COLUMN_PASSWORD + " = '" + password + "'",
				null, null, null, null);
		cursor.moveToFirst();
		User currentUser = cursorToUser(cursor);
		cursor.close();
		this.close();
		return currentUser;
	}

	/**
	 * Converts a row from the User table to a java User object.
	 * 
	 * @param cursor
	 *            the cursor pointing to the given row in the user table
	 * @return a User object with corresponding field values
	 */
	public User cursorToUser(Cursor cursor) {
		User user = new User();
		try {
			user.setId(cursor.getLong(0));
			user.setName(cursor.getString(1));
			user.setEmail(cursor.getString(2));
			user.setLogin(cursor.getString(3));
			user.setPassword(cursor.getString(4));
		} catch (CursorIndexOutOfBoundsException e) {
			user = null;
		}
		return user;
	}

}